package com.calvin.study.multithread.threadlocal;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

import com.calvin.study.utils.ThreadUtil;

import lombok.Data;


//将各线程中的bar变量累加10次，保证各线程的bar值安全。
public class ThreadLocalDemo01 {

	private static final ThreadLocal<Foo> LOCAL_FOO = new ThreadLocal<Foo>();

	@Data
	static class Foo {
		// 实例总数
		static final AtomicInteger AMOUNT = new AtomicInteger(0);
		// 对象的编号
		int index = 0;
		// 对象的内容
		int bar = 10;

		public Foo() {
			index = AMOUNT.incrementAndGet();// 总数增加,并且给对象的编号赋值
		}

		@Override
		public String toString() {
			return index + "@Foo{bar=" + bar + '}';
		}

	}

	public static void main(String[] args) {

		ThreadPoolExecutor threadPool = ThreadUtil.getMixedTargetThreadPool();
		
		// 提交5个任务， 将会用到5个线程
		for (int i = 0; i < 5; i++) {
			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					// 获取“线程本地变量” 中当前线程所绑定的值
					if (LOCAL_FOO.get() == null) {
						// 设置“线程本地变量” 中当前线程所绑定的值
						LOCAL_FOO.set(new Foo());
					}
					System.out.println("初始的本地值： " + LOCAL_FOO.get());
					// 每个线程执行10次
					for (int i = 0; i < 10; i++) {
						Foo foo = LOCAL_FOO.get();
						foo.setBar(foo.getBar() + 1); // 值增1
						ThreadUtil.sleepMilliSeconds(10);
					}
					System.out.println("累加10次之后的本地值： " + LOCAL_FOO.get());
					// 删除“线程本地变量” 中当前线程所绑定的值
					LOCAL_FOO.remove(); // 这点对于线程池中的线程尤其重要
				}
			});
		}
	}

}
